from ihome.api_1_0 import api
from ihome import redis_store, constants
from ihome.utils.response_code import RET
from ihome.utils.captcha.captcha import captcha
from ihome.models import User
from flask import current_app, jsonify, make_response,request
from ihome.libs.yuntongxun.SendTemplateSMS import CCP
import random


@api.route('/image_codes/<image_code_id>')
def get_image_code(image_code_id):
    '''
    获取图片验证码
    :param image_code_id: 每个验证码对应的编号
    :return:
    '''
    # 获取参数,image_code_id
    # 检验参数,这里不需要检验

    # 业务逻辑，把图片编号和内容存到redis中
    # redis中hash维护有效期的时候只能整体设置，单条维护记录，选用字符串
    name, text, img_data = captcha.generate_captcha()
    try:
        # 设置值，同时设置有效期
        redis_store.setex('image_code_%s' % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(error=RET.DBERR, msg='验证码图片保存失败')

    # 返回结果
    resp = make_response(img_data)
    resp.headers['Content-Type'] = "image/jpg"
    return resp

# GET /sms_codes/1822222?image_code=xxx&image_id=xxx
@api.route('/sms_codes/<re(r"1[34578]\d{9}"):mobile>')
def get_sms_code(mobile):
    '''获取短信验证码'''
    # 获取参数
    image_code = request.args.get("image_code")
    image_id = request.args.get("image_code_id")

    # 校验参数
    if not all([image_code, image_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 业务逻辑
    # - 判断图片验证码是否正确
    # - 判断手机号是否存在，如果不存在，生成短信验证码
    try:
        code_key = "image_code_%s" % image_id
        validate_code = redis_store.get(code_key).decode('utf-8')
    except Exception as e:
        return jsonify(errno=RET.DBERR, errmsg="数据库错误")

    # 删除图片验证码，防止用户使用一个图片验证多次
    try:
        redis_store.delete("image_code_%s" % image_id)
    except Exception as e:
        current_app.logger.error(e)

    # 判断验证码
    if validate_code:
        if validate_code.lower() != image_code.lower():
            return jsonify(errno=RET.DATAERR, errmsg="图片验证码错误")
    else:
        return jsonify(errno=RET.DATAERR, errmsg="图片验证码已过期")

    # 判断手机验证码间隔
    try:
        send_sms_code = redis_store.get("send_sms_code_%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)
    else:
        if send_sms_code:
            return jsonify(errno=RET.DATAEXIST, errmsg="间隔60s后重新发送")

    # 判断手机号是否存在
    try:
        user_id = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        user_id = None
    else: # 无异常时执行
        if user_id is not None:
            # 手机号已存在
            return jsonify(errno=RET.DATAEXIST, errmsg="数据已存在")

    # 发送短信
    sms_msg = "%06d" % random.randint(0, 999999)
    # 连接数据库时捕获异常
    try:
        redis_store.setex("sms_code_%s" % mobile, constants.IMAGE_CODE_REDIS_EXPIRES, sms_msg)
        redis_store.setex("send_sms_code_%s" % mobile, constants.SEND_SMS_CODE_EXPIRES, 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="redis错误")

    # 使用第三方sdk时捕获异常
    try:
        ccp = CCP()
        result = ccp.send_sms_template(mobile, [sms_msg, constants.IMAGE_CODE_REDIS_EXPIRES], 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="云通讯异常")

    if result == 0:
        return jsonify(errno=RET.OK, errmsg="发送成功")
    else:
        return jsonify(errno=RET.THIRDERR, errmsg="发送失败")